
function deepClone(target,map = new WeakMap()) {
    // * 这里要先判断是不是对象
    if (typeof target === 'object' && target !== null) {
        // * 对象的constructor属性是指对象所属类的构造函数。
        // * 它指向创建该对象的构造函数。通过constructor属性，我们可以获取对象所属类的构造函数，从而了解对象的类型信息。
        const cos = target.constructor
        // * 判断类型(这些类型也是对象) 这些类型直接返回? 这里不对！function regexp date应该new一个新的返回
        // * Map和Set也是要新建一个
        const reg = /^(Function|RegExp|Set|Map|Date)$/i
        if (reg.test(cos.name)) {
            return target
        }
        // * 判断数组或对象
        const obj = Array.isArray(target) ? [] : {}
        // * 使用map记录防止循环引用
        if (map.get(target)) {
            return map.get(target)
        }
        map.set(target, obj)
        for (let i in target) {
            // * 因为用的for in 所以这段必须加！判断是不是本身的属性
            if (target.hasOwnProperty(i)) {
                // * 递归clone
                obj[i] = deepClone(target[i],map)
            }
        }
        return obj
    }
    else return target
}
const obj = {name: 'John', age: [25,26,27]}
const obj2 = {name: 'John', age: [{c:1},26,27]}
const clonedObj = deepClone(obj)
const clonedObj2 = deepClone(obj2)
console.log(clonedObj) // { name: 'John', age: [ 25, 26, 27 ] }
console.log(clonedObj === obj) // false
console.log(clonedObj2) // {name: 'John', age: [{c:1},26,27]}
console.log(clonedObj2 === obj2) // false
